package com.scs.application.modules.wos.service.impl;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.BeanUtils;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.FileUtils;
import com.scs.application.modules.ext.controller.SysFileController;
import com.scs.application.modules.ext.entity.File;
import com.scs.application.modules.ext.service.FileService;
import com.scs.application.modules.wos.consts.TaskFlowStatus;
import com.scs.application.modules.wos.dto.WoTaskCreateDto;
import com.scs.application.modules.wos.entity.WosWoTask;
import com.scs.application.modules.wos.mapper.WosWoTaskMapper;
import com.scs.application.modules.wos.service.WosWoTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 *  工单任务 服务实现类
 */
@Service
public class WosWoTaskServiceImpl extends BaseServiceImpl<WosWoTaskMapper, WosWoTask> implements WosWoTaskService {
    @Autowired
    private FileService fileService;

    public WosWoTaskServiceImpl(SysFileController sysFileController) {
        super();
    }

    //外部系统调用-SCP系统-推送-创建工单-单个
    @Override
    @Transactional
    public void createOneForTpcItsm(WoTaskCreateDto createDto) {
        WosWoTask task = this.getOne(Wrappers.<WosWoTask>query().eq("task_id_itsm",createDto.getId()));
        BusinessException.throwErrorIf(task != null, "该任务已存在，请勿重复推送");
        task = new WosWoTask();
        BeanUtils.copyProperties(createDto, task);
        task.setTaskIdItsm(task.getId());
        task.setId(IdWorker.getIdStr());
        task.setFlowStatus(TaskFlowStatus.handle_start);
        saveOrUpdate(task);

        if (createDto.getApplyFileUrl() != null && !createDto.getApplyFileUrl().isEmpty()) {
            File fileSave;
            List<File> fileList = new ArrayList<>();
            for(String fileUrl: createDto.getApplyFileUrl()) {
                fileSave = new File();
                fileSave.setRefId(task.getId()+"_apply");
                fileSave.setRefTable("wos_wo_task");
                downloadToLocal(fileSave,fileUrl);
                fileList.add(fileSave);
            }
            fileService.saveBatch(fileList);
        }
    }


    private void downloadToLocal(File fileSave , String fileUrl) {

        //打开链接
        InputStream inStream = null;
        try {
            URL url = new URL(fileUrl );
            inStream = url.openStream();
            //得到图片的二进制数据，以二进制封装得到数据，具有通用性
            byte[] fileBytes = readInputStream(inStream);
            String fileName = UUID.randomUUID() + "." + FileUtils.getFileExtension(fileUrl);
            String fileSavePath = resPath + "wos_wo_task/" + fileName;
            java.io.File file = new java.io.File(fileSavePath);
            FileUtil.writeBytes(fileBytes, file);
            fileSave.setFilePath("/res/wos_wo_task/" + fileName);
            fileSave.setFileName(fileName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] readInputStream(InputStream inStream) throws Exception{
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度，如果为-1，代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while( (len=inStream.read(buffer)) != -1 ){
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }

    /**
     * @description:  任务处理
     * @param  task
     * @param  statusFrom   来源状态
     * @param  statusTo     目标状态
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WosWoTask handleStatus(WosWoTask task, String statusFrom, String statusTo) {
        WosWoTask taskDb = this.getById(task.getId());
        BusinessException.throwErrorIf(taskDb == null, "任务不存在，请刷新");
        BusinessException.throwErrorIf(!statusFrom.equals(taskDb.getFlowStatus()), "任务状态非法，请刷新");
        task.setFlowStatus(statusTo);
        switch (statusTo) {
            case TaskFlowStatus.handle_doing:{
                if (task.getHandleTimeBegin() == null) {
                    task.setHandleTimeBegin(DateUtils.nowDate2(DateUtils.YYYYMMDDHHMMSS_PATTER2));
                }
                break;
            }
            case TaskFlowStatus.handle_end:{
                if (task.getHandleTimeEnd() == null) {
                    task.setHandleTimeEnd(DateUtils.nowDate2(DateUtils.YYYYMMDDHHMMSS_PATTER2));
                }

                // 计算处理耗费时间
                task
                        .setHandleTimeCost(DateUtil.formatBetween(task.getHandleTimeBegin(),task.getHandleTimeEnd(), BetweenFormatter.Level.MINUTE))
                ;
                task.setTimeCost(DateUtil.between(task.getHandleTimeBegin(),task.getHandleTimeEnd(), DateUnit.MINUTE));
                break;
            }
        }
        this.updateById(task);
        return task;
    }
}
